package com.example.web.config;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.core.env.Environment;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.example.web.config.enums.DataSourceEnum;
import com.example.web.config.multiple.MultipleDataSource;

import lombok.extern.slf4j.Slf4j;
/**
 * <b>配置并创建数据源</b>
 * @author yzl
 *
 */
@Slf4j
@Configuration
@MapperScan("com.example.web.mapper*")
public class MyDatasourceConfiguration  {

	@Autowired
	private Environment env;

	/**
	 * 数据源1
	 * 
	 * @return
	 */
	@Bean("db1")
	@ConfigurationProperties(prefix = "spring.datasource.db1")
	public DataSource db1() {
		return DataSourceBuilder.create().build();
	}

	/**
	 * 数据源2
	 * @return
	 */
	@Bean("db2")
	@ConfigurationProperties(prefix = "spring.datasource.db2")
	public DataSource db2() {
		return DataSourceBuilder.create().build();
	}

	/**
	 * @Primary 给注解表示在同一个接口有多个实现类可以注入的时候，默认选择那个，而不是让@Autowied 注解报错
	 * @Qualifier 根据名称进行注入，通常是在具有相同的多个类型的实力的一个注入（列如有多个DataSource 的类型）
	 * @param db1
	 * @param db2
	 * @return
	 */
	@Bean("multipleDataSource")
	@Primary
	public MultipleDataSource multipleDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
		MultipleDataSource multipleDataSource = new MultipleDataSource();
		Map<Object, Object> targetDataSources = new HashMap<>();
		targetDataSources.put(DataSourceEnum.DB1.getValue(), db1);
		targetDataSources.put(DataSourceEnum.DB2.getValue(), db2);
		// 添加数据源
		multipleDataSource.setTargetDataSources(targetDataSources);
		// 设置默认数据源
		multipleDataSource.setDefaultTargetDataSource(db1);
		return multipleDataSource;
	}

	/**
	 * 根据数据源创建SqlSessionFactory
	 * @return
	 * @throws Exception
	 */
	@Bean("sqlSessionFactory")
	public SqlSessionFactory sqlSessionFactory() throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(multipleDataSource(db1(), db2()));
		
		bean.setTypeAliasesPackage(env.getProperty("mybatis.type-aliases-package")); // 指定基包
		bean.setMapperLocations(
				new PathMatchingResourcePatternResolver()
				.getResources(env.getProperty("mybatis.mapper-locations")));// 设置我们的xml文件路径
		//bean.setMapperLocations(
			//	new PathMatchingResourcePatternResolver()
				//.getResources("classpath:mapper/**/*Mapper.xml"));
		return bean.getObject();
	}

	/**
	 * 
	 * <descption> 配置事务管理 </descption>
	 * 
	 * @param
	 * @return
	 */
	@Bean
	public DataSourceTransactionManager tracsactionManager(MultipleDataSource ds) {
		return new DataSourceTransactionManager(ds);
	}
}
